/**
 * 
 */
package cn.com.rexen.rplus.sa.controller;

import cn.com.rexen.rplus.controller.CURDControllerSupport;
import cn.com.rexen.rplus.core.criteria.*;
import cn.com.rexen.rplus.core.service.IService;
import cn.com.rexen.rplus.sa.entity.Organization;
import cn.com.rexen.rplus.sa.entity.UserOrganization;
import cn.com.rexen.rplus.sa.model.OrganizationVO;
import cn.com.rexen.rplus.sa.model.PageVO;
import cn.com.rexen.rplus.sa.service.OrganizationService;
import cn.com.rexen.rplus.sa.service.UserService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * 组织机构controller.
 * 
 * @author zhanghai
 * 
 */
@Controller
@RequestMapping(value = OrganizationController.REQUEST_PATH)
public class OrganizationController extends CURDControllerSupport<Organization, OrganizationVO> {

    /**
     * 组织机构请求路径.
     */
    public static final String REQUEST_PATH = "org";

    /**
     * 机构service.
     */
    @Autowired
    private OrganizationService organizationService;

    @Autowired
    private UserService userService;

    /**
     * 机构实体对象.
     */
    private Organization organization;

    /*
     * (non-Javadoc)
     * 
     * @see cn.com.rexen.rplus.controller.CURDControllerSupport#getEntity()
     */
    @Override
    public Organization getEntity() {
        if (organization == null) {
            organization = new Organization();
        }
        return organization;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * cn.com.rexen.rplus.controller.CURDControllerSupport#getEntityService()
     */
    @Override
    protected IService getEntityService() {
        return organizationService;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * cn.com.rexen.rplus.controller.CURDControllerSupport#doList(javax.servlet
     * .http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    @Override
    public Page<Organization> doList(HttpServletRequest request, HttpServletResponse response) {

        Criteria criteria = organizationService.getCriteria(Organization.class);
        String pageSize = request.getParameter("pageSize");
        String page = request.getParameter("page");
        String parentId = request.getParameter("parentid");
        Pageable pageable = new PageRequest(page == null ? 0 : Integer.parseInt(page), pageSize == null ? DEFAULT_PAGESIZE
                : Integer.parseInt(pageSize));
        criteria.setPageable(pageable);
        if (StringUtils.isNotEmpty(parentId)) {
            criteria.add(Restrictions.eq("parentgroup", parentId));
        }
        Page<Organization> pageResult = organizationService.findWithPage(criteria);

        return pageResult;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * cn.com.rexen.rplus.controller.CURDControllerSupport#onShow(javax.servlet
     * .http.HttpServletRequest, javax.servlet.http.HttpServletResponse,
     * java.lang.Object, org.springframework.ui.ModelMap)
     */
//    @Override
    protected OrganizationVO onShow(HttpServletRequest request, HttpServletResponse response, Organization o, ModelMap mm) {
        if (o == null) {
            return new OrganizationVO();
        }
        Organization organization = (Organization) o;
        String parentId = organization.getParentId();
        String parentName = null;
        if (StringUtils.isNotEmpty(parentId)) {
            Organization organizationParent = organizationService.get(Organization.class, parentId);
            parentName = organizationParent == null ? "" : organizationParent.getName();
        }
        OrganizationVO ov = new OrganizationVO(organization.getId(), organization.getName(), parentName, "", parentId);
        return ov;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * cn.com.rexen.rplus.controller.CURDControllerSupport#afterList(javax.servlet
     * .http.HttpServletRequest, javax.servlet.http.HttpServletResponse,
     * org.springframework.ui.ModelMap, java.util.List)
     */
    @Override
    protected void afterList(HttpServletRequest request, HttpServletResponse response, ModelMap mm, Page page) {
        List<OrganizationVO> organizationVOList = new ArrayList<OrganizationVO>();
        if (page.getContent().size() > 0)
            for (Object object : page.getContent()) {
                Organization organization = (Organization) object;
                Organization organizationParent = null;
                if (organization.getParentId() != null) {
                    organizationParent = organizationService.get(Organization.class, organization.getParentId());
                }
                OrganizationVO ov = new OrganizationVO(organization.getId(), organization.getName(),
                        organizationParent == null ? "" : organizationParent.getName(), getApps().getId(),
                        organization.getParentId());
                organizationVOList.add(ov);
            }
        mm.addAttribute("data", organizationVOList);
        PageVO pageVO = new PageVO(page.getTotalPages(), page.getNumber(), page.getTotalElements());
        mm.addAttribute("page", pageVO);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * cn.com.rexen.rplus.controller.CURDControllerSupport#beforeSave(javax.
     * servlet .http.HttpServletRequest, java.lang.Object,
     * org.springframework.validation.BindException,
     * org.springframework.ui.ModelMap)
     */
    @Override
    protected void beforeSave(HttpServletRequest request, HttpServletResponse response, OrganizationVO entity,
            BindException errors, ModelMap mm) {
        organization = new Organization();
        organization.setId(organizationService.generateId());
        organization.setName(entity.getName());
        organization.setApp(getApps());
        if (StringUtils.isBlank(entity.getParentid())) {
            organization.setParentId(ROOT);
        } else {
            organization.setParentId(entity.getParentid());
        }
        organization.setLeaf(true);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * cn.com.rexen.rplus.controller.CURDControllerSupport#beforeUpdate(javax
     * .servlet.http.HttpServletRequest, java.lang.Object,
     * org.springframework.validation.BindException,
     * org.springframework.ui.ModelMap, java.lang.String)
     */
    @Override
    protected void beforeUpdate(HttpServletRequest request, HttpServletResponse response, OrganizationVO entity,
            BindException errors, ModelMap mm, String id) {

        if (id.equals(entity.getParentid())) {
            throw new RuntimeException("父节点与本节点重复.");
        }
        organization = organizationService.get(Organization.class, id);
        organization.setName(entity.getName());
        organization.setApp(getApps());
        if (StringUtils.isBlank(entity.getParentid())) {
            organization.setParentId(ROOT);
        } else {
            organization.setParentId(entity.getParentid());
        }
        organization.setLeaf(true);

    }

    /**
     * 通过资源父id获取资源列表.
     * 
     * @param parentId
     *            资源父id
     * @return 返回资源列表的json数据.
     */
    @RequestMapping(value = "/{parentId}/children", method = RequestMethod.GET)
    @ResponseBody
    public ModelMap children(@PathVariable String parentId) {
        ModelMap mm = new ModelMap();
        List<Organization> list = organizationService.getOrganizationListByParentId(parentId);
        List<OrganizationVO> organizationVOList = new ArrayList<OrganizationVO>();
        LOGGER.debug("afterlist@resource ,list:{} ", list);
        for (Object object : list) {
            Organization organization = (Organization) object;
            String parentgroupid = organization.getParentId();

            String parentName = null;
            if (StringUtils.isNotEmpty(parentgroupid)) {
                Organization organizationParent = organizationService.get(Organization.class, parentgroupid);
                if (organizationParent != null)
                    parentName = organizationParent.getName();
                else
                    parentName = "";
            }

            OrganizationVO organizationVO = new OrganizationVO(organization.getId(), organization.getName(),
                    parentName, organization.getApp().getId(), parentgroupid);
            List<Organization> isItemList = organizationService.getOrganizationListByParentId(organization.getId());
            if (isItemList == null || isItemList.size() <= 0) {
                organizationVO.setType("item");
            } else {
                organizationVO.setType("folder");
            }
            organizationVOList.add(organizationVO);
        }
        mm.addAttribute("data", organizationVOList);
        return mm;
    }

    @Override
    public void doDelete(Object object) throws Exception {
        Organization organization = (Organization) object;
        List<Organization> isItemList = organizationService.getOrganizationListByParentId(organization.getId());
        if (isItemList != null && isItemList.size() > 0) {
            throw new RuntimeException("有子结点不允许删除.");
        }
        Set<UserOrganization> userOrganizations = organization.getUserOrganizations();
        if (userOrganizations != null && userOrganizations.size() > 0) {
            throw new RuntimeException("此机构下有用户不允许删除.");
        }
        organizationService.delete(organization);
    }
}
